"""
数据库引擎主类
整合查询执行器、事务管理和索引系统
"""

from typing import Any, Dict, List, Optional
from storage.storage_manager import StorageManager
from storage.buffer_manager import BufferManager
from .query_executor import QueryExecutor
from auth.auth_manager import AuthManager
from auth.permission_manager import PermissionManager

class Transaction:
    """事务类"""
    
    def __init__(self, transaction_id: int):
        """初始化事务"""
        self.transaction_id = transaction_id
        self.status = 'ACTIVE'  # ACTIVE, COMMITTED, ABORTED
        self.operations = []  # 操作日志
        self.locks = set()  # 持有的锁
    
    def add_operation(self, operation: Dict[str, Any]):
        """添加操作到日志"""
        self.operations.append(operation)
    
    def commit(self):
        """提交事务"""
        self.status = 'COMMITTED'
    
    def abort(self):
        """回滚事务"""
        self.status = 'ABORTED'
        # 这里应该实现回滚逻辑
    
    def is_active(self) -> bool:
        """检查事务是否活跃"""
        return self.status == 'ACTIVE'

class DatabaseEngine:
    """数据库引擎"""
    
    def __init__(self, storage_manager: StorageManager):
        """初始化数据库引擎"""
        self.storage_manager = storage_manager
        self.buffer_manager = BufferManager()
        self.buffer_manager.set_storage_manager(storage_manager)
        self.query_executor = QueryExecutor(storage_manager, self.buffer_manager)
        
        # 认证和权限管理
        self.auth_manager = AuthManager(storage_manager)
        self.permission_manager = PermissionManager(storage_manager, self.auth_manager)
        
        # 事务管理
        self.transactions: Dict[int, Transaction] = {}
        self.next_transaction_id = 1
        self.current_transaction: Optional[Transaction] = None
        
        # 锁管理（简化实现）
        self.locks: Dict[str, int] = {}  # 表名 -> 事务ID
    
    def execute(self, query_plan: Dict[str, Any]) -> Any:
        """执行查询计划"""
        try:
            # 处理权限相关的特殊命令
            if query_plan['type'] in ['LOGIN', 'LOGOUT', 'CREATE_USER', 'GRANT', 'REVOKE', 'SHOW_GRANTS', 'SHOW_USERS', 'CHANGE_PASSWORD']:
                return self._execute_auth_command(query_plan)
            
            # 检查用户是否已认证
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录 (使用 LOGIN username password)"
            
            # 检查权限
            if not self._check_permission(query_plan):
                return "错误: 权限不足，无法执行此操作"
            
            # 开始事务（如果还没有活跃事务）
            if not self.current_transaction:
                self.begin_transaction()
            
            # 记录操作
            self.current_transaction.add_operation(query_plan)
            
            # 执行查询
            result = self.query_executor.execute(query_plan)
            
            # 如果是创建表，设置表所有者
            if query_plan['type'] == 'CREATE_TABLE':
                current_user = self.auth_manager.get_current_user()
                if current_user:
                    self.permission_manager.set_table_owner(query_plan['table_name'], current_user['user_id'])
            
            # 自动提交（简化实现）
            self.commit_transaction()
            
            return result
            
        except Exception as e:
            # 回滚事务
            if self.current_transaction:
                self.abort_transaction()
            raise e
    
    def begin_transaction(self) -> int:
        """开始事务"""
        transaction_id = self.next_transaction_id
        self.next_transaction_id += 1
        
        transaction = Transaction(transaction_id)
        self.transactions[transaction_id] = transaction
        self.current_transaction = transaction
        
        return transaction_id
    
    def commit_transaction(self):
        """提交当前事务"""
        if self.current_transaction:
            # 刷新所有脏页
            self.buffer_manager.flush_all()
            
            # 提交事务
            self.current_transaction.commit()
            
            # 释放锁
            self._release_locks(self.current_transaction.transaction_id)
            
            # 清除当前事务
            self.current_transaction = None
    
    def abort_transaction(self):
        """回滚当前事务"""
        if self.current_transaction:
            # 回滚事务
            self.current_transaction.abort()
            
            # 释放锁
            self._release_locks(self.current_transaction.transaction_id)
            
            # 清除当前事务
            self.current_transaction = None
    
    def _acquire_lock(self, table_name: str) -> bool:
        """获取表锁（简化实现）"""
        if table_name in self.locks:
            if self.locks[table_name] != self.current_transaction.transaction_id:
                return False  # 锁被其他事务持有
        
        self.locks[table_name] = self.current_transaction.transaction_id
        self.current_transaction.locks.add(table_name)
        return True
    
    def _release_locks(self, transaction_id: int):
        """释放事务持有的锁"""
        for table_name in list(self.locks.keys()):
            if self.locks[table_name] == transaction_id:
                del self.locks[table_name]
    
    def get_database_info(self) -> Dict[str, Any]:
        """获取数据库信息"""
        tables = self.storage_manager.list_tables()
        table_info = {}
        
        for table_name in tables:
            table_info[table_name] = {
                'record_count': self.storage_manager.get_record_count(table_name),
                'page_count': self.storage_manager.get_page_count(table_name),
                'schema': self.storage_manager.get_schema(table_name)
            }
        
        buffer_stats = self.buffer_manager.get_buffer_stats()
        
        return {
            'tables': table_info,
            'buffer_stats': buffer_stats,
            'active_transactions': len([t for t in self.transactions.values() if t.is_active()])
        }
    
    def print_database_info(self):
        """打印数据库信息"""
        info = self.get_database_info()
        
        print("数据库信息:")
        print(f"  表数量: {len(info['tables'])}")
        print(f"  活跃事务数: {info['active_transactions']}")
        
        print("\n缓冲区统计:")
        stats = info['buffer_stats']
        print(f"  总帧数: {stats['total_frames']}/{stats['buffer_size']}")
        print(f"  脏页数: {stats['dirty_frames']}")
        print(f"  固定页数: {stats['pinned_frames']}")
        
        print("\n表信息:")
        for table_name, table_info in info['tables'].items():
            print(f"  表: {table_name}")
            print(f"    记录数: {table_info['record_count']}")
            print(f"    页面数: {table_info['page_count']}")
            
            schema = table_info['schema']
            if schema:
                print("    列:")
                for col_name, col_def in schema['columns'].items():
                    print(f"      {col_name}: {col_def['type']}")
    
    def backup_database(self, backup_path: str) -> bool:
        """备份数据库（简化实现）"""
        try:
            import shutil
            import os
            
            if os.path.exists(backup_path):
                shutil.rmtree(backup_path)
            
            shutil.copytree(self.storage_manager.data_dir, backup_path)
            return True
            
        except Exception as e:
            print(f"备份失败: {e}")
            return False
    
    def restore_database(self, backup_path: str) -> bool:
        """恢复数据库（简化实现）"""
        try:
            import shutil
            import os
            
            if not os.path.exists(backup_path):
                print(f"备份路径不存在: {backup_path}")
                return False
            
            # 清空当前数据
            if os.path.exists(self.storage_manager.data_dir):
                shutil.rmtree(self.storage_manager.data_dir)
            
            # 恢复数据
            shutil.copytree(backup_path, self.storage_manager.data_dir)
            
            # 重新加载元数据
            self.storage_manager.load_metadata()
            
            return True
            
        except Exception as e:
            print(f"恢复失败: {e}")
            return False
    
    def optimize_database(self):
        """优化数据库（简化实现）"""
        print("开始数据库优化...")
        
        # 刷新所有脏页
        self.buffer_manager.flush_all()
        
        # 这里可以添加更多优化逻辑，如：
        # - 重建索引
        # - 整理页面碎片
        # - 更新统计信息
        
        print("数据库优化完成")
    
    def shutdown(self):
        """关闭数据库引擎"""
        print("正在关闭数据库引擎...")
        
        # 提交所有活跃事务
        for transaction in self.transactions.values():
            if transaction.is_active():
                transaction.commit()
        
        # 刷新所有脏页
        self.buffer_manager.flush_all()
        
        # 保存元数据
        self.storage_manager.save_metadata()
        
        print("数据库引擎已关闭")
    
    def _check_permission(self, query_plan: Dict[str, Any]) -> bool:
        """检查用户权限"""
        current_user = self.auth_manager.get_current_user()
        if not current_user:
            return False
        
        user_id = current_user['user_id']
        query_type = query_plan['type']
        
        # 根据查询类型确定需要的权限
        if query_type == 'SELECT':
            table_name = query_plan['table_name']
            return self.permission_manager.check_permission(user_id, table_name, 'SELECT')
        
        elif query_type == 'INSERT':
            table_name = query_plan['table_name']
            return self.permission_manager.check_permission(user_id, table_name, 'INSERT')
        
        elif query_type == 'UPDATE':
            table_name = query_plan['table_name']
            return self.permission_manager.check_permission(user_id, table_name, 'UPDATE')
        
        elif query_type == 'DELETE':
            table_name = query_plan['table_name']
            return self.permission_manager.check_permission(user_id, table_name, 'DELETE')
        
        elif query_type == 'CREATE_TABLE':
            # 创建表需要CREATE权限（这里简化处理，所有认证用户都可以创建表）
            return True
        
        elif query_type == 'DROP_TABLE':
            table_name = query_plan['table_name']
            return self.permission_manager.check_permission(user_id, table_name, 'DROP')
        
        return False
    
    def _execute_auth_command(self, query_plan: Dict[str, Any]) -> str:
        """执行认证相关命令"""
        query_type = query_plan['type']
        
        if query_type == 'LOGIN':
            username = query_plan['username']
            password = query_plan['password']
            if self.auth_manager.login(username, password):
                return f"登录成功! 欢迎, {username}"
            else:
                return "登录失败: 用户名或密码错误"
        
        elif query_type == 'LOGOUT':
            if self.auth_manager.logout():
                return "已成功登出"
            else:
                return "登出失败: 当前没有登录用户"
        
        elif query_type == 'CREATE_USER':
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录"
            
            username = query_plan['username']
            password = query_plan['password']
            role = query_plan['role']
            
            if self.auth_manager.create_user(username, password, role):
                return f"用户 {username} 创建成功"
            else:
                return f"创建用户失败: 用户名 {username} 可能已存在"
        
        elif query_type == 'GRANT':
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录"
            
            current_user = self.auth_manager.get_current_user()
            permissions = query_plan['permissions']
            table_name = query_plan['table_name']
            username = query_plan['username']
            
            # 获取目标用户ID
            target_user = self._get_user_by_username(username)
            if not target_user:
                return f"错误: 用户 {username} 不存在"
            
            granted_count = 0
            for permission in permissions:
                if self.permission_manager.grant_permission(
                    target_user['user_id'], table_name, permission, current_user['user_id']
                ):
                    granted_count += 1
            
            if granted_count > 0:
                return f"成功授予 {granted_count} 个权限给用户 {username}"
            else:
                return f"授权失败: 没有权限或权限已存在"
        
        elif query_type == 'REVOKE':
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录"
            
            current_user = self.auth_manager.get_current_user()
            permissions = query_plan['permissions']
            table_name = query_plan['table_name']
            username = query_plan['username']
            
            # 获取目标用户ID
            target_user = self._get_user_by_username(username)
            if not target_user:
                return f"错误: 用户 {username} 不存在"
            
            revoked_count = 0
            for permission in permissions:
                if self.permission_manager.revoke_permission(
                    target_user['user_id'], table_name, permission, current_user['user_id']
                ):
                    revoked_count += 1
            
            if revoked_count > 0:
                return f"成功撤销 {revoked_count} 个权限从用户 {username}"
            else:
                return f"撤销权限失败: 没有权限或权限不存在"
        
        elif query_type == 'SHOW_GRANTS':
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录"
            
            username = query_plan['username']
            target_user = self._get_user_by_username(username)
            if not target_user:
                return f"错误: 用户 {username} 不存在"
            
            permissions = self.permission_manager.get_user_permissions(target_user['user_id'])
            if not permissions:
                return f"用户 {username} 没有任何权限"
            
            result = f"用户 {username} 的权限:\n"
            for perm in permissions:
                result += f"  {perm['table_name']}: {perm['permission_type']} ({perm['description']})\n"
            
            return result.strip()
        
        elif query_type == 'SHOW_USERS':
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录"
            
            current_user = self.auth_manager.get_current_user()
            if current_user['role'] != 'admin':
                return "错误: 只有管理员可以查看用户列表"
            
            users = self.auth_manager.list_users()
            if not users:
                return "没有找到用户"
            
            result = "用户列表:\n"
            for user in users:
                status = "活跃" if user['is_active'] else "停用"
                result += f"  {user['username']} (ID: {user['user_id']}, 角色: {user['role']}, 状态: {status})\n"
            
            return result.strip()
        
        elif query_type == 'CHANGE_PASSWORD':
            if not self.auth_manager.is_authenticated():
                return "错误: 请先登录"
            
            old_password = query_plan['old_password']
            new_password = query_plan['new_password']
            
            if self.auth_manager.change_password(old_password, new_password):
                return "密码修改成功"
            else:
                return "密码修改失败: 旧密码错误"
        
        return "未知的认证命令"
    
    def _get_user_by_username(self, username: str) -> Optional[Dict[str, Any]]:
        """根据用户名获取用户信息"""
        try:
            users = self.storage_manager.query_table(
                'system_users',
                {'username': username}
            )
            return users[0] if users else None
        except:
            return None

# 测试函数
if __name__ == "__main__":
    storage = StorageManager("test_data")
    engine = DatabaseEngine(storage)
    
    try:
        # 测试创建表
        create_plan = {
            'type': 'CREATE_TABLE',
            'table_name': 'users',
            'schema': {
                'columns': {
                    'id': {'type': {'type': 'int'}},
                    'name': {'type': {'type': 'varchar', 'length': 50}},
                    'age': {'type': {'type': 'int'}}
                },
                'primary_key': 'id'
            }
        }
        
        print("创建表...")
        result = engine.execute(create_plan)
        print(result)
        
        # 测试插入数据
        insert_plans = [
            {
                'type': 'INSERT',
                'table_name': 'users',
                'values': [1, 'Alice', 25],
                'columns': ['id', 'name', 'age']
            },
            {
                'type': 'INSERT',
                'table_name': 'users',
                'values': [2, 'Bob', 30],
                'columns': ['id', 'name', 'age']
            }
        ]
        
        print("\n插入数据...")
        for plan in insert_plans:
            result = engine.execute(plan)
            print(result)
        
        # 测试查询
        select_plan = {
            'type': 'SELECT',
            'table_name': 'users',
            'columns': '*',
            'where': None,
            'schema': create_plan['schema']
        }
        
        print("\n查询数据...")
        result = engine.execute(select_plan)
        print(f"查询结果: {result}")
        
        # 打印数据库信息
        print("\n数据库信息:")
        engine.print_database_info()
        
    finally:
        # 关闭引擎
        engine.shutdown()
